#include "pch.h"
#include "InputManager.h"

using namespace Windows::UI::Core;
using namespace Windows::UI::Input;
using namespace Windows::UI;
using namespace Windows::Foundation;
using namespace Microsoft::WRL;
using namespace Windows::Devices::Input;
using namespace Windows::System;


uint InputManager::GetPressedPointVecSize()
{
	return m_PressedPointVec.size();
}

 PointInfo& InputManager::GetPressedPointAt(uint index)
{
	return m_PressedPointVec.at(index);
}

PointPressStatus InputManager::GetPointPressStatus()
{
	return m_PointPressStatus;
}

InputManager::InputManager():m_PointPressStatus(PointStatus_None)
{

}

void InputManager::Initialize(
    _In_ CoreWindow^ window
    )
{
    window->PointerPressed +=
        ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &InputManager::OnPointerPressed);

    window->PointerMoved +=
        ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &InputManager::OnPointerMoved);

    window->PointerReleased +=
        ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &InputManager::OnPointerReleased);

    window->PointerExited +=
        ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &InputManager::OnPointerExited);

    window->KeyDown +=
        ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &InputManager::OnKeyDown);

    window->KeyUp +=
        ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &InputManager::OnKeyUp);

	window->PointerWheelChanged += 
		ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &InputManager::OnPointerWheel);

    // There is a separate handler for mouse only relative mouse movement events.
    MouseDevice::GetForCurrentView()->MouseMoved +=
        ref new TypedEventHandler<MouseDevice^, MouseEventArgs^>(this, &InputManager::OnMouseMoved);

    ResetState();


}

void InputManager::ResetState()
{

}

void InputManager::UpdatePointStaus(Windows::UI::Core::PointerEventArgs^ args)
{
	uint vec_size = m_PressedPointVec.size();
	switch (m_PressedPointVec.size())
	{
	case 1:
		{
			m_PointPressStatus = PointStatus_One;
		}
		break;
	case 2:
		{
			m_PointPressStatus = PointStatus_Two;
		}
		break;
	default:
		m_PointPressStatus = PointStatus_None;
		break;
	}
}

void InputManager::OnPointerPressed(
    _In_ CoreWindow^ /* sender */,
    _In_ PointerEventArgs^ args
    )
{
	bool flag = StateMachine::Instance()->CurrentState()->OnPointerPressed(args);

	PointerPoint^ point = args->CurrentPoint;
	PointInfo info;
	info.point_id = point->PointerId;
	info.last_position = float2(point->Position.X, point->Position.Y);
	m_PressedPointVec.push_back(info);
	UpdatePointStaus(args);
}

//----------------------------------------------------------------------

void InputManager::OnPointerMoved(
    _In_ CoreWindow^ /* sender */,
    _In_ PointerEventArgs^ args
    )
{
	bool flag = StateMachine::Instance()->CurrentState()->OnPointerMoved(args);
}

void InputManager::OnMouseMoved(
	_In_ MouseDevice^ /* mouseDevice */,
	_In_ MouseEventArgs^ args
	)
{
	//float2 delta;
	//delta.x = args->MouseDelta.X;
	//delta.y = args->MouseDelta.Y;
}

//----------------------------------------------------------------------

void InputManager::OnPointerReleased(
	_In_ CoreWindow^ /* sender */,
	_In_ PointerEventArgs^ args
	)
{
	bool flag = StateMachine::Instance()->CurrentState()->OnPointerReleased(args);
	PointerPoint^ point = args->CurrentPoint;

	auto itor = m_PressedPointVec.begin();

	while(itor != m_PressedPointVec.end())
	{
		if(itor->point_id == point->PointerId)
		{
			itor = m_PressedPointVec.erase(itor);
		}
		else
		{
			itor ++;
		}
	}

	UpdatePointStaus(args);
}

//----------------------------------------------------------------------

void InputManager::OnPointerExited(
	_In_ CoreWindow^ /* sender */,
	_In_ PointerEventArgs^ args
	)
{

}

//----------------------------------------------------------------------

void InputManager::OnKeyDown(
	_In_ CoreWindow^ /* sender */,
	_In_ KeyEventArgs^ args
	)
{
	
	Windows::System::VirtualKey Key;
    Key = args->VirtualKey;

	bool flag = StateMachine::Instance()->CurrentState()->OnKeyDown(Key);

	if (Key == VirtualKey::Q)
	{
		DirectX2DRender::Instance()->GetCurrentCamera()->ZoomIn();
	}
	
	if (Key == VirtualKey::E)
	{
		DirectX2DRender::Instance()->GetCurrentCamera()->ZoomOut();
	}

	if (Key == VirtualKey::W)
	{
		DirectX2DRender::Instance()->GetCurrentCamera()->SetMoveFlag((1 << Camera2D::VerticalUp));
	}

	if (Key == VirtualKey::A)
	{
		DirectX2DRender::Instance()->GetCurrentCamera()->SetMoveFlag((1 << Camera2D::HorizontalLeft));
	}

	if (Key == VirtualKey::S)
	{
		DirectX2DRender::Instance()->GetCurrentCamera()->SetMoveFlag((1 << Camera2D::VerticalDown));
	}

	if (Key == VirtualKey::D)
	{
		DirectX2DRender::Instance()->GetCurrentCamera()->SetMoveFlag((1 << Camera2D::HorizontalRight));
	}

	if (Key == VirtualKey::T)
	{
		DirectX2DRender::Instance()->sprite = RenderObjectManager::Instance()->CreateSprite(L"data/texture.dds",float2(1,0),float2(2,2),45.f);
	}

	if (Key == VirtualKey::Y)
	{
		DirectX2DRender::Instance()->sprite = nullptr;
	}

	if (Key == VirtualKey::U)
	{
		BasicLoader^ loader = ref new BasicLoader(DirectX2DRender::Instance()->GetDevice().Get());
		Platform::Array<byte>^ data;
		
		loader->LoadRawData(L"data/Robot2.xml", data);

		BuildingScene::Instance()->ParseRobot(reinterpret_cast<char*>(data->Data), data->Length);
	}

	if (Key == VirtualKey::I)
	{
		BuildingScene::Instance()->GameStart();
	}

	if (Key == VirtualKey::O)
	{
		BuildingScene::Instance()->GenerateJoint();
	}

	if (Key == VirtualKey::P)
	{
		BuildingScene::Instance()->GameStart();
	}

	if (Key == VirtualKey::L)
	{
		BuildingScene::Instance()->SaveRobot2XML();
	}
	
}

//----------------------------------------------------------------------

void InputManager::OnKeyUp(
	_In_ CoreWindow^ /* sender */,
	_In_ KeyEventArgs^ args
	)
{
	
}

void InputManager::OnPointerWheel(
	_In_ CoreWindow^ /* sender */,
	_In_ PointerEventArgs^ args
	)
{

}
